home *** CD-ROM | disk | FTP | other *** search
- ; File: tjos.asm
- ; Auth: Richard Foard
-
-
- TITLE tjos
- ;
- ; Routines in this module (Microsoft C subroutine linkage):
- ;
- ;
- ; init_os()
- ;
- ; Prepares TJ/OS environment for use. Upon exit, caller is running
- ; as first task.
- ;
- ;
- ; int fork(stack, stack_size)
- ; char *stack;
- ; int stack_size;
- ;
- ; Creates and activates a task. Returns 'false' to the calling task and
- ; 'true' to the newly created task.
- ;
- ;
- ; yield()
- ;
- ; Allows a context switch to occur.
- ;
- ;
- ; wait(event_counter)
- ; int *event_counter;
- ;
- ; Waits for an event.
- ;
- ;
- ; post(event_counter)
- ; int *event_counter;
- ;
- ; Signals that an event has occurred.
- ;
- ;
- ; stop()
- ;
- ; Deactivates and destroys the calling task.
- ;
-
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
- _TEXT ENDS
-
- CONST SEGMENT WORD PUBLIC 'CONST'
- CONST ENDS
-
- _BSS SEGMENT WORD PUBLIC 'BSS'
- _BSS ENDS
-
- _DATA SEGMENT WORD PUBLIC 'DATA'
- _DATA ENDS
-
- DGROUP GROUP CONST, _BSS, _DATA
- ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
-
- PUBLIC _init_os
- PUBLIC _yield
- PUBLIC _fork
- PUBLIC _wait
- PUBLIC _post
- PUBLIC _stop
- PUBLIC __chkstk
-
- _TEXT SEGMENT
- EXTRN _exit:NEAR
- _TEXT ENDS
-
- _BSS SEGMENT
- max_tasks equ 8
- ct_limit equ max_tasks * 2
- task_tbl dw max_tasks dup (0)
- cur_task dw 0
- actv_tasks dw 0
- EVEN
- _BSS ENDS
-
- ;---------------------------------------------------------------------------
- _TEXT SEGMENT
-
- ;-------------------------
- _init_os PROC NEAR ;init_os() {
- mov cur_task,0 ; cur_task = 0;
- mov actv_tasks,1 ; actv_tasks = 1;
- sub ax,ax ; task_tbl[0..max_tasks - 1] = 0;
- mov cx,max_tasks ;
- mov bx,offset task_tbl ;
- ini_1: ;
- mov [bx],ax ;
- add bx,2 ;
- dec cx ;
- jnz ini_1 ;
- ret ;
- _init_os ENDP ;}
-
- ;-------------------------
- _yield PROC NEAR ;yield()
- push bp ; (preserve BP)
- mov bx,offset task_tbl ; task_tbl[cur_task] = SP;
- mov ax,cur_task ;
- add bx,ax ;
- mov [bx],sp ;
- yie_0: ;
- add ax,2 ; do {
- cmp ax,ct_limit ; cur_task = (cur_task + 2)
- jne yie_1 ; % ct_limit;
- sub ax,ax ;
- yie_1: ;
- mov bx,offset task_tbl ; } while (task_tbl[cur_task] == 0);
- add bx,ax ;
- push ax ;
- mov ax,[bx] ;
- or ax,ax ;
- pop ax ;
- jnz yie_2 ;
- jmp yie_0 ;
- yie_2: ;
- mov bx,offset task_tbl ; SP = task_tbl[cur_task];
- mov cur_task,ax ;
- add bx,ax ;
- mov sp,[bx] ;
- pop bp ; (restore BP)
- mov ax,1 ; return(1);
- ret ;}
- _yield ENDP
-
- ;-------------------------
- _fork PROC NEAR ;int fork(stack, stack_size) {
- mov ax,actv_tasks ; if (actv_tasks == max_tasks)
- cmp ax,max_tasks ; exit(1);
- jne for_0 ;
- mov ax,1 ;
- push ax ;
- call _exit ;
- for_0: ;
- inc ax ; actv_tasks = actv_tasks + 1;
- mov actv_tasks,ax ;
- pop dx ; (caller's return addr)
- pop ax ; (new task stack base)
- pop bx ; (new task stack size)
- push bx ; (restore caller's stack)
- push ax ;
- push dx ;
- push bp ; (preserve caller's BP)
- mov bp,sp ; (and caller's SP)
- add ax,bx ; (establish new task's base sp)
- sub ax,4 ; (allow pop of fork's parameters)
- mov sp,ax ;
- push dx ; (new task return addr)
- push ax ; (and bp register image)
- mov bx,offset task_tbl ; (find free slot in task_tbl)
- for_1: mov ax,[bx] ;
- or ax,ax ;
- jz for_2 ;
- add bx,2 ;
- jmp for_1 ;
- for_2: mov [bx],sp ; (install new task in task_tbl)
- mov sp,bp ; (restore caller's stack)
- pop bp ; (and BP)
- sub ax,ax ; return (0);
- ret ;}
- _fork ENDP
-
- ;-------------------------
- _wait PROC NEAR ;wait(event_counter) {
- wai_0: pop cx ;
- pop bx ;
- push bx ;
- push cx ;
- cli ; (protect test-and-set)
- mov ax,[bx] ;
- or ax,ax ;
- jnz wai_1 ; while (*event_counter == 0)
- sti ;
- call _yield ; yield();
- jmp wai_0 ;
- wai_1: dec ax ; --(*event_counter);
- mov [bx],ax ;
- sti ;
- ret ;}
- _wait ENDP ;
-
- ;-------------------------
- _post PROC NEAR ;post(event_counter) {
- pop cx ;
- pop bx ;
- push bx ;
- inc word ptr [bx] ; ++(*event_counter);
- jmp cx ;
- _post ENDP ;}
-
- ;-------------------------
- _stop PROC NEAR ;stop() {
- mov ax,actv_tasks ; if (--actv_tasks == 0) exit(0);
- dec ax ;
- jnz sto_0 ;
- sub ax,ax ;
- push ax ;
- call _exit ;
- sto_0: ;
- mov actv_tasks,ax ;
- mov bx,offset task_tbl ;
- mov ax,cur_task ;
- add bx,ax ; task_tbl[cur_task] = 0;
- mov word ptr [bx],0 ; (join 'yield' to switch context)
- jmp yie_0 ;}
- _stop ENDP
-
- ;-------------------------
- __chkstk: ;chkstk:
- pop cx ; (allocate AX bytes of stack space)
- mov bx,sp ;
- sub bx,ax ;
- mov sp,bx ;
- jmp cx ;
-
- _TEXT ENDS
- END
-